#pragma once

#include <vector>
#include <boost/any.hpp>
#include <boost/assert.hpp>
#include <type_traits>
#include <torch/torch.h>

#define ENABLE_CAST \
                    operator core_type & () {return core;}\
                    operator const core_type & () const {return core;}

#define DECL_CORE(CoreType)\
                    using core_type = CoreType;\
                    core_type core;

namespace utils {

    template<class Mapped, class T>
    std::vector<Mapped> map_to_core(const std::vector<T> &v) {
        std::vector<Mapped> v_ret;
        for (auto x : v)v_ret.push_back(x.core);
        return (v_ret);
    }

    template<class Wrapper, class T>
    std::vector<Wrapper>
    map_to_wrapper(const std::vector<T> &v) {
        std::vector<Wrapper> v_ret;
        for (auto x : v)v_ret.emplace_back(Wrapper(x));
        return (v_ret);
    }

    //检测一个any是否能转换成某种类型，RTTI
    template<typename T>
    bool can_cast_to(const boost::any &any) {
        return any.type() == typeid(T);
    }

    //尝试转换
    template<typename T>
    T try_any_cast(boost::any &any) {
        BOOST_ASSERT_MSG(can_cast_to<T>(any), "any cast failed");
        return boost::any_cast<T>(any);
    }

    //尝试转换
    template<typename T>
    T try_any_cast(const boost::any &any) {
        BOOST_ASSERT_MSG(can_cast_to<T>(any), "any cast failed");
        return boost::any_cast<T>(any);
    }
}
